import type { DatabaseConnectionType } from './connection.js';
import { DatabaseConnection } from './connection.js';
import { initializeModels } from './models/index.js';
import { RepositoryFactory } from './repositories/index.js';
import * as fs from 'fs';
import * as path from 'path';

/**
 * 数据库管理器 - 负责数据库初始化、迁移和管理
 */
export class DatabaseManager {
  private connection: DatabaseConnectionType;
  private repositories: RepositoryFactory;
  private models: any;

  constructor() {
    this.connection = DatabaseConnection;
    this.repositories = RepositoryFactory.getInstance(this.connection);
  }

  /**
   * 初始化数据库连接和模型
   */
  async initialize(): Promise<void> {
    try {
      console.log('🚀 开始初始化数据库...');
      
      // 1. 建立数据库连接
      const sequelize = await this.connection.connect();
      console.log('✅ 数据库连接已建立');
      
      // 2. 初始化模型
      this.models = initializeModels(sequelize);
      console.log('✅ 数据模型已初始化');
      
      // 3. 同步数据库结构
      await this.syncDatabase();
      
      console.log('🎉 数据库初始化完成');
    } catch (error) {
      console.error('❌ 数据库初始化失败:', error);
      throw error;
    }
  }

  /**
   * 同步数据库结构
   */
  async syncDatabase(options?: {
    force?: boolean;
    alter?: boolean;
  }): Promise<void> {
    try {
      const sequelize = this.connection.getSequelize();
      
      if (options?.force) {
        console.log('⚠️  强制重建数据库表...');
        await sequelize.sync({ force: true });
      } else if (options?.alter) {
        console.log('🔄 更新数据库表结构...');
        await sequelize.sync({ alter: true });
      } else {
        console.log('📊 同步数据库表结构...');
        await sequelize.sync();
      }
      
      console.log('✅ 数据库结构同步完成');
    } catch (error) {
      console.error('❌ 数据库结构同步失败:', error);
      throw error;
    }
  }

  /**
   * 执行SQL迁移文件
   */
  async runMigration(migrationFile: string): Promise<void> {
    try {
      const migrationPath = path.join(process.cwd(), 'src', 'database', 'migrations', migrationFile);
      
      if (!fs.existsSync(migrationPath)) {
        throw new Error(`Migration file not found: ${migrationPath}`);
      }

      const sql = fs.readFileSync(migrationPath, 'utf8');
      const statements = sql
        .split(';')
        .map(stmt => stmt.trim())
        .filter(stmt => stmt.length > 0);

      console.log(`📝 执行迁移文件: ${migrationFile}`);
      
      for (const statement of statements) {
        await this.connection.executeRawQuery(statement);
      }
      
      console.log(`✅ 迁移文件 ${migrationFile} 执行完成`);
    } catch (error) {
      console.error(`❌ 迁移文件 ${migrationFile} 执行失败:`, error);
      throw error;
    }
  }

  /**
   * 执行种子数据
   */
  async runSeeders(seedFiles?: string[]): Promise<void> {
    try {
      const seedDir = path.join(process.cwd(), 'src', 'database', 'seeders');
      
      if (!fs.existsSync(seedDir)) {
        console.log('⚠️  种子数据目录不存在，跳过种子数据执行');
        return;
      }

      const files = seedFiles || fs.readdirSync(seedDir).filter(file => file.endsWith('.ts'));
      
      for (const file of files) {
        await this.runSeeder(file);
      }
      
      console.log('🌱 所有种子数据执行完成');
    } catch (error) {
      console.error('❌ 种子数据执行失败:', error);
      throw error;
    }
  }

  /**
   * 执行单个种子文件
   */
  async runSeeder(seedFile: string): Promise<void> {
    try {
      const seedPath = path.join(process.cwd(), 'src', 'database', 'seeders', seedFile);
      
      if (!fs.existsSync(seedPath)) {
        throw new Error(`Seed file not found: ${seedPath}`);
      }

      console.log(`🌱 执行种子文件: ${seedFile}`);
      
      // 动态导入种子文件
      const seederModule = await import(seedPath);
      const seeder = seederModule.default || seederModule;
      
      if (typeof seeder === 'function') {
        await seeder(this.repositories);
      } else if (seeder.up && typeof seeder.up === 'function') {
        await seeder.up(this.repositories);
      } else {
        throw new Error(`Invalid seeder format in ${seedFile}`);
      }
      
      console.log(`✅ 种子文件 ${seedFile} 执行完成`);
    } catch (error) {
      console.error(`❌ 种子文件 ${seedFile} 执行失败:`, error);
      throw error;
    }
  }

  /**
   * 检查数据库健康状态
   */
  async healthCheck(): Promise<{
    database: any;
    repositories: any;
    models: boolean;
  }> {
    try {
      const dbHealth = await this.connection.healthCheck();
      const repoHealth = await this.repositories.checkHealth();
      
      return {
        database: dbHealth,
        repositories: repoHealth,
        models: !!this.models,
      };
    } catch (error) {
      console.error('❌ 数据库健康检查失败:', error);
      throw error;
    }
  }

  /**
   * 清空所有数据
   */
  async truncateAllTables(): Promise<void> {
    try {
      console.log('🧹 清空所有数据表...');
      
      const sequelize = this.connection.getSequelize();
      
      // 禁用外键约束
      await sequelize.query('SET FOREIGN_KEY_CHECKS = 0');
      
      // 获取所有表名并清空
      const tables = Object.keys(this.models);
      for (const tableName of tables) {
        const model = this.models[tableName];
        if (model && model.destroy) {
          await model.destroy({ where: {}, truncate: true });
          console.log(`✅ 清空表: ${tableName}`);
        }
      }
      
      // 重新启用外键约束
      await sequelize.query('SET FOREIGN_KEY_CHECKS = 1');
      
      console.log('🧹 所有数据表清空完成');
    } catch (error) {
      console.error('❌ 清空数据表失败:', error);
      throw error;
    }
  }

  /**
   * 关闭数据库连接
   */
  async close(): Promise<void> {
    try {
      await this.connection.disconnect();
      console.log('📡 数据库连接已关闭');
    } catch (error) {
      console.error('❌ 关闭数据库连接失败:', error);
      throw error;
    }
  }

  /**
   * 获取 Repository 工厂
   */
  getRepositories(): RepositoryFactory {
    return this.repositories;
  }

  /**
   * 获取数据库连接
   */
  getConnection(): DatabaseConnectionType {
    return this.connection;
  }

  /**
   * 获取模型
   */
  getModels(): any {
    return this.models;
  }
}